using System;
using System.Collections.Generic;
using System.Text;
using Xfinity.Physics;
using Microsoft.Xna.Framework.Content.Pipeline;
using System.Xml.Serialization;
using System.IO;
using System.Xml;
using System.Reflection;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content.Pipeline.Serialization.Compiler;
using System.Diagnostics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;

namespace Xfinity.ContentProcessors
{
    [ContentTypeWriter]
    public class MaterialTypeWriter : ContentTypeWriter<Material>
    {
        protected override void Write(ContentWriter output, Material value)
        {
            try
            {
                output.WriteObject<Material>(value, this);
                Trace.Write("Done writing material.");
            }
            catch (InvalidOperationException e)
            {
                InvalidOperationException ex = e;
                Exception inner = ex.InnerException;
                string source = ex.Source;
                string whole = ex.ToString();
                string message = e.Message;
                Debugger.Launch();
            }
        }

        public override string GetRuntimeReader(Microsoft.Xna.Framework.TargetPlatform targetPlatform)
        {
            return typeof(Xfinity.Physics.Material.MaterialReader).AssemblyQualifiedName;
        }
        public override string GetRuntimeType(Microsoft.Xna.Framework.TargetPlatform targetPlatform)
        {
            return typeof(Material).AssemblyQualifiedName;
        }
    }


    [ContentProcessor(DisplayName = "Material processor")]
    public class XfinityMaterialProcessor : ContentProcessor<Material, Material>
    {

        public override Material Process(Material input, ContentProcessorContext context)
        {
            return input;
        }
    }


    [ContentImporter(".material", DefaultProcessor = "MaterialProcessor", CacheImportedData = true, DisplayName = "Xfinity material")]
    public class MaterialImporter : ContentImporter<Material>
    {
        public override Material Import(string filename, ContentImporterContext context)
        {
            Material material = null;
            XmlSerializer serializer = new XmlSerializer(typeof(Material), new Type[] { typeof(Color) });
            FileStream stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
            XmlReader reader = XmlReader.Create(stream);
            reader.Read();
            XmlReader node = reader.ReadSubtree();
            if (!serializer.CanDeserialize(node))
            {
                context.Logger.LogImportantMessage("Cannot process " + filename);
                return null;
            }

            try
            {
                material = serializer.Deserialize(node) as Material;
            }
            catch (InvalidOperationException e)
            {
                string message = e.Message;
                string message2 = message;
                Debugger.Launch();
            }

            Type matType = typeof(Material);

            foreach (PropertyInfo p in matType.GetProperties())
            {

                if (!p.Name.EndsWith("Name"))
                {
                    continue;
                }
                if (p.Name == "Name")
                {
                    continue;
                }


                Type t = matType.GetProperty(p.Name.Replace("Name", "")).PropertyType;
                string path = "";
                if (t == typeof(Texture2D))
                {
                    path = "..\\Textures\\";
                }
                else if (t == typeof(Effect) && p.GetValue(material, null).ToString().ToLower() != "basiceffect")
                {
                    path = "..\\Effects\\";
                }
                else
                {
                    path = "..\\";
                }
                string absolutePath = Path.GetFullPath(path);
                context.AddDependency(Path.Combine(absolutePath, p.GetValue(material, null).ToString()));

            }
            return material;
        }
    }
}
